package com.china08.yxyapi.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import com.china08.yxyapi.config.RabbitConfig;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 发送推送:[应用内消息|自定义消息|透传消息]
 * 
 */
public class JpushForMessageUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(JpushForMessageUtil.class);

    private static ObjectMapper objectMapper = new ObjectMapper();

    private static RestTemplate restTemplate;

    /**
     * 组装消息数据(对外发送消息)
     * 
     * @param moduleId（模块id）
     *            参数：1、schoolNoitce 2、classNotice 3、educationNotice
     *            5、homeworkNotice 6、chengjidan 7、classMoments
     * @param roleId（角色id）
     *            参数：0、ROLE_TEACHER 1、ROLE_PARENTS 2、ROLE_SCH_ADMIN
     *            3、ROLE_EDU_ADMIN
     * @param schoolId（学校id）
     * @param tags（接收tag）
     * @param tag_ands
     *            （接收tag_and关系）
     */
    public static void sendMessage(Integer moduleId, List<Integer> roleId, String schoolId, List<String> tags,
            List<String> tag_ands) {
        Map<String, String> returnMap = new HashMap<String, String>();
        Map<String, String> msg = new HashMap<String, String>();

        String yxyApiYxUrl = SpringContextUtil.getCtx().getEnvironment().getProperty("yx.rest.api.yx.path");

        // 学校id
        if (null == schoolId) {
            LOGGER.info("发送取消: 接收者schoolId参数为空");
            return;
        }
        if (schoolId.isEmpty()) {
            LOGGER.info("发送取消: 接收者schoolId参数为空");
            return;
        }
        msg.put("schoolId", schoolId);

        // 模块id
        if (null == moduleId) {
            LOGGER.info("发送取消: 接收者moduleId参数为空");
            return;
        }
        switch (moduleId) {
        case 1:
            msg.put("moduleId", "schoolNotice");
            break;
        case 2:
            msg.put("moduleId", "classNotice");
            break;
        case 3:
            msg.put("moduleId", "educationNotice");
            break;
        case 4:
            msg.put("moduleId", "attendanceToStudent");
            break;
        case 5:
            msg.put("moduleId", "classMoments");
            break;
        case 6:
            msg.put("moduleId", "smallTasks");
            break;
        case 7:
            msg.put("moduleId", "kaoqindaoban");
            break;
        case 8:
            msg.put("moduleId", "homeworkNotice");
            break;
        case 9:
            msg.put("moduleId", "chengjidan");
            break;
        case 100:
            msg.put("moduleId", "chenjian");
            break;
        default:
            LOGGER.info("发送取消: 接收者moduleId参数为空");
            return;
        }

        // 获取推送开关是否开启&能否发送推送
        try {
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE.toString());
            Map<String, Object> formMap = new HashMap<String, Object>();
            formMap.put("jpushName", msg.get("moduleId"));
            formMap.put("jpushRole", roleId);
            HttpEntity<Map<String, Object>> formEntity = new HttpEntity<Map<String, Object>>(formMap, headers);
            restTemplate = new RestTemplate();
            JpushForCompRespModel httpResult = restTemplate.postForObject(yxyApiYxUrl + "/comm/jpush/comp/app/switch",
                    formEntity, JpushForCompRespModel.class);

            if (!httpResult.isTure) { return; }
        } catch (Exception e) {
            LOGGER.info("获取推送开关接口异常：" + e.getMessage());
        }

        // 角色id
        String[] roleName = new String[] { "ROLE_TEACHER", "ROLE_PARENTS", "ROLE_SCH_ADMIN", "ROLE_EDU_ADMIN" };
        if (null == roleId) {
            LOGGER.info("发送取消: 接收者roleId参数为空");
            return;
        }
        if (roleId.isEmpty()) {
            LOGGER.info("发送取消: 接收者roleId参数为空");
            return;
        }

        List<String> roleLst = new ArrayList<String>();
        for (Integer index : roleId) {
            if (index > 3) {
                LOGGER.info("发送取消: 接收者roleId参数异常");
                return;
            }
            roleLst.add(roleName[index]);
        }
        msg.put("roleId", StringUtils.join(roleLst.toArray(), ","));

        // tag用户
        if (null == tags) {
            LOGGER.info("发送取消: tags接收者为空");
            return;
        }
        if (tags.isEmpty()) {
            LOGGER.info("发送取消: tags接收者为空");
            return;
        }

        // tag_and数据
        if (null != tag_ands) {
            if (!tag_ands.isEmpty()) {
                if (tag_ands.size() > 20) {
                    LOGGER.info("发送取消: tags_and参数");
                    return;
                }
                returnMap.put("msgTag_and", StringUtils.join(tag_ands.toArray(), ","));
            }
        }

        returnMap.put("msgReceivers", StringUtils.join(tags.toArray(), ","));

        // 消息通知转换为json
        String mapJson = "";

        try {
            mapJson = objectMapper.writeValueAsString(msg);
        } catch (JsonProcessingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            LOGGER.info("发送取消: 组装数据异常");
        }

        returnMap.put("msgContent", mapJson);

        try {
            SpringContextUtil.getBean(RabbitTemplate.class).convertAndSend(RabbitConfig.JPUSH_FOR_MESSAGE, returnMap);
        } catch (AmqpException e) {
            LOGGER.info("发送准备失败: RabbitMQ发送失败");
            return;
        }
        LOGGER.info("发送准备完毕: 消息数据组装成功，准备发送");
    }

    public static void sendMessageTiming(Integer moduleId, List<Integer> roleId, String schoolId, List<String> tags,
            List<String> tag_ands, Date date) {
        Map<String, String> returnMap = new HashMap<String, String>();
        Map<String, String> msg = new HashMap<String, String>();

        String yxyApiYxUrl = SpringContextUtil.getCtx().getEnvironment().getProperty("yx.rest.api.yx.path");

        // 学校id
        if (null == schoolId) {
            LOGGER.info("发送取消: 接收者schoolId参数为空");
            return;
        }
        if (schoolId.isEmpty()) {
            LOGGER.info("发送取消: 接收者schoolId参数为空");
            return;
        }
        msg.put("schoolId", schoolId);

        // 模块id
        if (null == moduleId) {
            LOGGER.info("发送取消: 接收者moduleId参数为空");
            return;
        }
        switch (moduleId) {
        case 1:
            msg.put("moduleId", "schoolNotice");
            break;
        case 2:
            msg.put("moduleId", "classNotice");
            break;
        case 3:
            msg.put("moduleId", "educationNotice");
            break;
        case 4:
            msg.put("moduleId", "attendanceToStudent");
            break;
        case 5:
            msg.put("moduleId", "classMoments");
            break;
        case 6:
            msg.put("moduleId", "smallTasks");
            break;
        case 7:
            msg.put("moduleId", "kaoqindaoban");
            break;
        case 8:
            msg.put("moduleId", "homeworkNotice");
            break;
        case 9:
            msg.put("moduleId", "chengjidan");
            break;
        case 100:
            msg.put("moduleId", "chenjian");
            break;
        default:
            LOGGER.info("发送取消: 接收者moduleId参数为空");
            return;
        }

        // 获取推送开关是否开启&能否发送推送
        try {
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE.toString());
            Map<String, Object> formMap = new HashMap<String, Object>();
            formMap.put("jpushName", msg.get("moduleId"));
            formMap.put("jpushRole", roleId);
            HttpEntity<Map<String, Object>> formEntity = new HttpEntity<Map<String, Object>>(formMap, headers);
            restTemplate = new RestTemplate();
            JpushForCompRespModel httpResult = restTemplate.postForObject(yxyApiYxUrl + "/comm/jpush/comp/app/switch",
                    formEntity, JpushForCompRespModel.class);

            if (!httpResult.isTure) { return; }
        } catch (Exception e) {
            LOGGER.info("获取推送开关接口异常：" + e.getMessage());
        }

        // 角色id
        String[] roleName = new String[] { "ROLE_TEACHER", "ROLE_PARENTS", "ROLE_SCH_ADMIN", "ROLE_EDU_ADMIN" };
        if (null == roleId) {
            LOGGER.info("发送取消: 接收者roleId参数为空");
            return;
        }
        if (roleId.isEmpty()) {
            LOGGER.info("发送取消: 接收者roleId参数为空");
            return;
        }

        List<String> roleLst = new ArrayList<String>();
        for (Integer index : roleId) {
            if (index > 3) {
                LOGGER.info("发送取消: 接收者roleId参数异常");
                return;
            }
            roleLst.add(roleName[index]);
        }
        msg.put("roleId", StringUtils.join(roleLst.toArray(), ","));

        // tag用户
        if (null == tags) {
            LOGGER.info("发送取消: tags接收者为空");
            return;
        }
        if (tags.isEmpty()) {
            LOGGER.info("发送取消: tags接收者为空");
            return;
        }

        // tag_and数据
        if (null != tag_ands) {
            if (!tag_ands.isEmpty()) {
                if (tag_ands.size() > 20) {
                    LOGGER.info("发送取消: tags_and参数");
                    return;
                }
                returnMap.put("msgTag_and", StringUtils.join(tag_ands.toArray(), ","));
            }
        }

        returnMap.put("msgReceivers", StringUtils.join(tags.toArray(), ","));

        // 消息通知转换为json
        String mapJson = "";

        try {
            mapJson = objectMapper.writeValueAsString(msg);
        } catch (JsonProcessingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            LOGGER.info("发送取消: 组装数据异常");
        }

        returnMap.put("msgContent", mapJson);

        // 日期
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        returnMap.put("date", df.format(date));

        try {
            SpringContextUtil.getBean(RabbitTemplate.class).convertAndSend(RabbitConfig.JPUSH_FOR_MESSAGE, returnMap);
        } catch (AmqpException e) {
            LOGGER.info("发送准备失败: RabbitMQ发送失败");
            return;
        }
        LOGGER.info("发送准备完毕: 消息数据组装成功，准备发送");
    }

    /**
     * 电子书包消息推送（消息）
     * 
     * @param moduleId（模块id）-只针对电子书包业务
     * @param roleId（角色id）
     *            参数：ROLE_TEACHER、ROLE_PARENTS、ROLE_SCH_ADMIN、ROLE_EDU_ADMIN
     * @param schoolId（学校id）
     * @param tags（接收tag）
     * @param tag_ands（接收tag_and关系）
     * @param date（定时发送时间）
     */
    public static void sendMessagePack(String moduleId, List<String> roleId, String schoolId, List<String> tags,
            List<String> tag_ands, Date date) {

        Map<String, String> returnMap = new HashMap<String, String>();
        Map<String, String> msg = new HashMap<String, String>();

        // 学校id
        if (null == schoolId) {
            LOGGER.info("发送取消: 接收者schoolId参数为空");
            return;
        }
        if (schoolId.isEmpty()) {
            LOGGER.info("发送取消: 接收者schoolId参数为空");
            return;
        }
        msg.put("schoolId", schoolId);

        // 模块id
        if (null == moduleId) {
            LOGGER.info("发送取消: 接收者moduleId参数为空");
            return;
        }

        msg.put("moduleId", moduleId);

        // 角色id
        String[] roleName = new String[] { "ROLE_TEACHER", "ROLE_PARENTS", "ROLE_SCH_ADMIN", "ROLE_EDU_ADMIN" };
        if (null == roleId) {
            LOGGER.info("发送取消: 接收者roleId参数为空");
            return;
        }
        if (roleId.isEmpty()) {
            LOGGER.info("发送取消: 接收者roleId参数为空");
            return;
        }

        for (String index : roleId) {
            if (!Arrays.asList(roleName).contains(index)) {
                LOGGER.info("发送取消: 接收者roleId参数异常");
                return;
            }
        }
        msg.put("roleId", StringUtils.join(roleId.toArray(), ","));

        // tag用户
        if (null == tags) {
            LOGGER.info("发送取消: tags接收者为空");
            return;
        }
        if (tags.isEmpty()) {
            LOGGER.info("发送取消: tags接收者为空");
            return;
        }

        // tag_and数据
        if (null != tag_ands) {
            if (!tag_ands.isEmpty()) {
                if (tag_ands.size() > 20) {
                    LOGGER.info("发送取消: tags_and参数");
                    return;
                }
                returnMap.put("msgTag_and", StringUtils.join(tag_ands.toArray(), ","));
            }
        }

        returnMap.put("msgReceivers", StringUtils.join(tags.toArray(), ","));

        // 消息通知转换为json
        String mapJson = "";

        try {
            mapJson = objectMapper.writeValueAsString(msg);
        } catch (JsonProcessingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            LOGGER.info("发送取消: 组装数据异常");
        }

        returnMap.put("msgContent", mapJson);

        // 日期
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        returnMap.put("date", df.format(date));

        // 电子书包标识
        returnMap.put("flag", "epack");

        try {
            SpringContextUtil.getBean(RabbitTemplate.class).convertAndSend(RabbitConfig.JPUSH_FOR_MESSAGE, returnMap);
        } catch (AmqpException e) {
            LOGGER.info("发送准备失败: RabbitMQ发送失败");
            return;
        }
        LOGGER.info("发送准备完毕: 消息数据组装成功，准备发送");
    }

    protected static class JpushForCompRespModel {
        public boolean isTure = false;
    }

}
